home *** CD-ROM | disk | FTP | other *** search
/ Gekikoh Dennoh Club 7 / Gekikoh Dennoh Club Vol. 7 (Japan).7z / Gekikoh Dennoh Club Vol. 7 (Japan) (Track 01).bin / games / otoko / source.lzh / FuncEnemy / lboss03z.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-06-14  |  6.9 KB  |  307 lines

  1. /* 3面ボスザコ (03z = 03 zako) */
  2. /* 一度に4基出現する小さいボス */
  3. #include <xsp2lib.h>
  4.  
  5. #include "../otoko.h"
  6. #include "../player.h"
  7. #include "../enemy.h"
  8. #include "../eshot.h"
  9. #include "../effect.h"
  10. #include "../entry.h"
  11. #include "../priority.h"
  12. #include "../sound.h"
  13. #include "../psearch.h"
  14.  
  15.  
  16. #define SPEED_LASER        30
  17.  
  18. #define HP_0    300        /* 耐久力 */
  19.  
  20. #define SPEED_1        28    /* 横移動の加速度 */
  21. #define SPEED_1N    20    /* 横移動の加速度を足す回数 */
  22. #define SPEED_2        12    /* 撤退時の加速度 */
  23. #define SPEED_2N    24    /* 撤退時の加速度を足す回数 */
  24. #define SPEED_3        16    /* 爆発時の加速度 */
  25. #define SPEED_3N    32    /* 爆発時の加速度を足す回数 */
  26.  
  27. #define SPEED_SHOT1    12    /* 1段階目扇型ショット速度 */
  28. #define SPEED_SHOT2    10    /* 2段階目伸びるショットの一番遅い弾の速度 */
  29.  
  30. #define ENTRY_CONTROL_ADD    10    /* entry_control に足す値 */
  31.  
  32. #define SEQ_DEATH    3
  33.  
  34. enum {
  35.     MOVETO_L = 0,
  36.     MOVETO_R,
  37. };
  38.  
  39. static short EnemyMoveLBoss03Z (ENEMY *);
  40. static void EnemyTiniLBoss03Z (ENEMY *);
  41.  
  42.  
  43. void EnemyInitLBoss03Z (ENEMY * p)
  44. {
  45.     p->vx = 0;
  46.     p->vy = 4 << 16;
  47.  
  48.     p->hit_px = 24;
  49.     p->hit_py = 16;
  50.     p->hit_sx = 24;
  51.     p->hit_sy = 16;
  52.     p->hit_cx = 6;
  53.     p->timer = 0;
  54.     p->damage = 0;
  55.     p->flash = 0;
  56.     p->hp = HP_0;
  57.     p->seq = 0;
  58.     p->pt = obj_lboss03 + 8;
  59.     p->angle = 0;
  60.     p->core_pt = sp_core01;
  61.     p->core_info = PALET_CORE_BLUE | PRIORITY_BOSS;
  62.     p->m_work = 0;
  63.     p->s_work = 0;
  64.     p->func_enemy_move = EnemyMoveLBoss03Z;
  65.     p->func_enemy_tini = EnemyTiniLBoss03Z;
  66.  
  67.     if (SHORT_LX < 128 + 16)
  68.         p->cwork = 0;
  69.     else
  70.         p->cwork = !0;
  71.  
  72.     entry_control += ENTRY_CONTROL_ADD;
  73. }
  74.  
  75.  
  76.  
  77. static short EnemyMoveLBoss03Z (ENEMY * p)
  78. {
  79.     signed short offset1[32][2] =    /* 銀玉の座標オフセット */
  80.     {
  81.         {-16, 16},
  82.         {-18, 12},
  83.         {-20, 8},
  84.         {-22, 4},
  85.         {-22, 0},
  86.         {-22, -4},
  87.         {-20, -8},
  88.         {-18, -12},
  89.         {-16, -16},
  90.         {-12, -18},
  91.         {-8, -20},
  92.         {-4, -22},
  93.         {0, -22},
  94.         {4, -22},
  95.         {8, -20},
  96.         {12, -18},
  97.         {16, -16},
  98.         {18, -12},
  99.         {20, -8},
  100.         {22, -4},
  101.         {22, 0},
  102.         {22, 4},
  103.         {20, 8},
  104.         {18, 12},
  105.         {16, 16},
  106.         {12, 18},
  107.         {8, 20},
  108.         {4, 22},
  109.         {0, 22},
  110.         {-4, 22},
  111.         {-8, 20},
  112.         {-12, 18},
  113.     };
  114.  
  115.     /* 速度を足して上位ワード(固定整数部)だけ取り出す */
  116.     p->x = (p->lx += p->vx) >> 16;
  117.     p->y = (p->ly += p->vy) >> 16;
  118.     p->pt++;
  119.     p->angle++;
  120.  
  121.  
  122.     switch (p->seq) {
  123.         /* 登場直後、減速する */
  124.     case 0:
  125.         p->vy -= 4096;
  126.         if (p->vy < 0) {
  127.             p->seq++;
  128.             p->vy = 0;
  129.             if (p->cwork == 0) {
  130.                 SubEnemyMoveToInit (p, SHORT_LX + 128, SHORT_LY - 16, SPEED_1, SPEED_1N);
  131.                 p->m_work = MOVETO_L;    /* 次の移動方向 */
  132.             } else {
  133.                 SubEnemyMoveToInit (p, SHORT_LX - 128, SHORT_LY - 16, SPEED_1, SPEED_1N);
  134.                 p->m_work = MOVETO_R;
  135.             }
  136.             p->m_work2 = p->m_work3 = p->s_work = 0;
  137.         }
  138.         break;
  139.  
  140.         /* 上空で移動&攻撃 */
  141.     case 1:
  142.         if (SubEnemyMoveTo (p) < 0) {
  143.             short m_work_table[2] =
  144.             {MOVETO_R, MOVETO_L};
  145.             signed short dx_table[8] =
  146.             {48, -32, 48, -48, 32, -48, 0, 0};
  147.             signed short dy_table[8] =
  148.             {-16, 8, 16, -24, 32, -80, 0, 0};
  149.  
  150.             if (p->m_work3++ > 24) {
  151.                 p->seq++;    /* 撤退 */
  152.                 SubEnemyMoveToInit (p, SHORT_LX, 256 + 128, SPEED_2, SPEED_2N);
  153.             } else {
  154.                 p->m_work2++;
  155.                 switch (p->m_work2) {
  156.                 case 6:    /* 自機に突っ込んでくる */
  157.                     p->work = SHORT_LX;    /* 現在の座標を保存 */
  158.                     p->work2 = SHORT_LY + 64;
  159.                     SubEnemyMoveToInit (p, player->x, player->y, SPEED_1, SPEED_1N);
  160.                     break;
  161.                 case 7:    /* 自機に突っ込んだ後戻る */
  162.                     SubEnemyMoveToInit (p, p->work, p->work2, SPEED_1, SPEED_1N);
  163.                     break;
  164.                 case 8:
  165.                     p->m_work2 = 0;
  166.                     /* ここに break がない事に注意 */
  167.                 default:
  168.                     if (p->cwork == 0) {
  169.                         SubEnemyMoveToInit (p, SHORT_LX + dx_table[p->m_work2], SHORT_LY + dy_table[p->m_work2], SPEED_1, SPEED_1N);
  170.                     } else {
  171.                         SubEnemyMoveToInit (p, SHORT_LX - dx_table[p->m_work2], SHORT_LY + dy_table[p->m_work2], SPEED_1, SPEED_1N);
  172.                     }
  173.                     p->m_work = m_work_table[p->m_work];    /* 次の移動方向 */
  174.                     break;
  175.                 }
  176.             }
  177.         }
  178.         /* 次に攻撃処理 */
  179.         if (p->m_work2 < 6) {
  180.             p->s_work++;
  181.             switch (p->s_work) {
  182. #define    INTERVAL    3
  183.             case INTERVAL * 1:
  184.             case INTERVAL * 2:
  185.             case INTERVAL * 3:
  186.             case INTERVAL * 4:
  187.             case INTERVAL * 5:
  188.                 EnemyInit (ENEMY_LBOSS03G, SHORT_LX, SHORT_LY, 0, p);    /* 銀玉を発射 */
  189.                 break;
  190.             case INTERVAL * 30:
  191.                 p->s_work = 0;
  192.                 break;
  193.             default:
  194.                 break;
  195.             }
  196.             if (p->s_work < INTERVAL * 6) {
  197.                 p->pt++;
  198.                 p->angle++;
  199.             }
  200.         }
  201.         break;
  202.  
  203.     case 2:
  204.     default:
  205.         if (SubEnemyMoveTo (p) < 0)
  206.             SubEnemyMoveToInit (p, SHORT_LX, 256 + 128, SPEED_2, SPEED_2N);
  207.         /* 画面外に出たら消去 */
  208.         if (SHORT_LY > 256 + 64)
  209.             return (-1);    /* 消去 */
  210.         break;
  211.  
  212.     case SEQ_DEATH:    /* 死んだ時の処理 */
  213.         if (SHORT_VY < 4)
  214.             p->vy += 16384;
  215.         if (p->m_work++ > 16) {
  216.             p->m_work = 0;
  217.             EffectInit (EFFECT_EXPL, 0, p->x, p->y);
  218.             SoundSetSE (SE_EXPL);
  219.         }
  220.         /* 画面外に出たら消去 */
  221.         if (SHORT_LY > 256 + 64)
  222.             return (-1);    /* 消去 */
  223.         break;
  224.     }
  225.  
  226.  
  227.     /* 自機ショットに当たった時の処理 */
  228.     if ((p->seq != SEQ_DEATH) && (p->damage)) {
  229.         p->info = PALET_RED | PRIORITY_BOSS_PARTS_L;
  230.         p->damage_core = 0;
  231.         if ((p->hp -= p->damage) <= 0) {
  232.             /* 死んだ */
  233.             p->seq = SEQ_DEATH;
  234.             p->m_work = 0;
  235.             p->hit_px = p->hit_py = p->hit_sx = p->hit_sy = p->hit_cx = 0;
  236.             if (p->core_info == (PALET_CORE_RED | PRIORITY_BOSS))
  237.                 EffectInit (EFFECT_POINTS_RED, POINTS_5000, p->x, p->y);
  238.             else
  239.                 EffectInit (EFFECT_POINTS_BLUE, POINTS_3000, p->x, p->y);
  240.             if (disp_level == DISP_LEVEL_HIGH)
  241.                 EffectInit (EFFECT_HAHENMINI, 0, p->x, p->y);
  242.         }
  243.         p->damage = 0;
  244.         p->flash = TIMER_FLASH_DAMAGE;
  245.     } else {
  246.         if (((p->flash++ > TIMER_FLASH_RED) && (p->hp < 100)) && (p->seq != SEQ_DEATH)) {
  247.             p->info = PALET_RED | PRIORITY_BOSS_PARTS;
  248.             if (p->flash > TIMER_FLASH_NORMAL)
  249.                 p->flash = 0;
  250.         } else {
  251.             if (p->arg == 0)
  252.                 p->info = PALET_LBOSS03 | PRIORITY_BOSS_PARTS_L;
  253.             else
  254.                 p->info = PALET_LBOSS03_1 | PRIORITY_BOSS_PARTS_L;
  255.         }
  256.     }
  257.     if (p->pt > obj_lboss03 + 8 + 7)
  258.         p->pt -= 8;
  259.     xobj_set_st (p);
  260.  
  261.  
  262.     /* コアの表示 */
  263.     if (p->seq != SEQ_DEATH) {    /* 死んだらコア状態は変化させない */
  264.         if (player->y < p->y + 96)    /* 自機との座標の差が小さければ赤 */
  265.             p->core_info = PALET_CORE_RED | PRIORITY_BOSS;
  266.         else
  267.             p->core_info = PALET_CORE_BLUE | PRIORITY_BOSS;
  268.     }
  269.     p->core_x = p->x - 8;    /* コアの中心は (-8,-8) ドットずれる */
  270.     p->core_y = p->y;
  271.     xsp_set_st (&(p->core_x));
  272.  
  273.     /* 周囲の銀球の表示 */
  274.     {
  275.         unsigned char a, a2;
  276.         a = (p->angle &= 31);
  277.  
  278.         if (p->hp > HP_0 / 5 * 4) {
  279.             xsp_set (p->x + offset1[a][0] - 8, p->y + offset1[a][1], sp_lboss03g, PALET_LBOSS03 | PRIORITY_BOSS_PARTS_L);
  280.         }
  281.         if (p->hp > HP_0 / 5 * 3) {
  282.             a2 = a + 8;
  283.             a2 &= 31;
  284.             xsp_set (p->x + offset1[a2][0] - 8, p->y + offset1[a2][1], sp_lboss03g, PALET_LBOSS03 | PRIORITY_BOSS_PARTS_L);
  285.         }
  286.         if (p->hp > HP_0 / 5 * 2) {
  287.             a2 = a + 16;
  288.             a2 &= 31;
  289.             xsp_set (p->x + offset1[a2][0] - 8, p->y + offset1[a2][1], sp_lboss03g, PALET_LBOSS03 | PRIORITY_BOSS_PARTS_L);
  290.         }
  291.         if (p->hp > HP_0 / 5 * 1) {
  292.             a2 = a + 24;
  293.             a2 &= 31;
  294.             xsp_set (p->x + offset1[a2][0] - 8, p->y + offset1[a2][1], sp_lboss03g, PALET_LBOSS03 | PRIORITY_BOSS_PARTS_L);
  295.         }
  296.     }
  297.  
  298.     return (0);
  299. }
  300.  
  301.  
  302.  
  303. static void EnemyTiniLBoss03Z (ENEMY * p)
  304. {
  305.     entry_control -= ENTRY_CONTROL_ADD;
  306. }
  307.